#  ActiveRecord Hacks:
#
#  1. Dynamic "nice_date"
#  	Basically, i got tired of typing object.created_at.strftime("%m-%d-%Y") 
#  	so i came up with the following method_missing hack for any Time
#  	attribute in an ActiveRecord object. Just prepend "nice_" in 
#  	front of any Datetime 	attribute and you will get a nicely formatted 
#  	date string.  Plus some other	goodies :)
#  	
#  	
#  	Examples:
#  	object.created_at												# => Mon Dec 04 12:36:55 CST 2006
#  	object.nice_created_at									# => "12-04-2006"  (mm-dd-YYYY)
#  	object.nice_created_at(:euro) 					# => "04-12-2006"  (dd-mm-YYYY)
#  
#  	plus, for you guys (and gals) that like using slashes instead of dashes:
#  	object.nice_created_at(:slash) 					# => "12/04/2006"  (mm/dd/YYYY)
#  	object.nice_created_at(:euro_slash)			# => "04/12/2006"  (dd/mm/YYYY)
#  	
#  	and finally:
#  	object.nice_created_at(:rss) 						# => "Mon, 04 Dec 2006 12:36:55 -0600"  (rfc822)
#  	
#  	NOTE**
#  	If the method does not return a value of class Time, then a NoMethodError 
#  	will be thrown
#	
#
#  2. Dynamic SEO formatting.
#		Any method that returns a string can use this dynamic method.
#		This method will create an SEO friendly string out of the attribute 
#		chosen (for use mainly in URLS).  It will append the objects id 
#		(not the object_id, but the id key from the database) so that you 
#		can use params[:id] and not have to create new routes.
#		
#		Example:
#		puts object.id 						# => 1
#		object.title 				= " Rails is freaking awesome, didn't you know that?  "
#		puts object.seo_title 		# => "1-rails-is-freaking-awesome-didnt-you-know-that"
#		
#		
#  3. nice_name
#  	This one is pretty simple.  I found myself adding this same method to 
#  	alot of my applications.  Basically it looks for an attribute called "first_name" 
#  	and one called "last_name" and combines them together with a space in between.
#  	
#  	Example:
#  	object.first_name 	= "jake"
#  	object.last_name 		= "varghese"
#  	object.nice_name  	# => "jake varghese"
#  	
#  	NOTE**
#  	If the method doesn't have EITHER first_name or last_name, then a NoMethodError 
#  	will be thrown.  It must have both attributes
#	
#  4. create/new from XML
# 	Create an ActiveRecord Object from XML.  This method relies on the basics of AR's 
#		current to_xml string (basically, it must be formatted as such).
#		The differences between new_from_xml and create_from_xml are the same as the differences
#		between AR.new and AR.create
# 	
#   If your XML string contains multiple records, it will parse out each record and 
#		create an object.  The "multiple record" call returns an array like find(:all)
#
#
# 	Example:
# 	person = Person.create_from_xml(xml_string)



class ActiveRecord::Base

	def nice_name
		if @attributes.include?("first_name") && @attributes.include?("last_name")
			return first_name + " " + last_name
		else
			raise NoMethodError
		end
	end

	def method_missing_with_nice_time(method_id, *args, &block)
		method_name = method_id.to_s
		if md = /nice_([_a-zA-Z]\w*)/.match(method_name)
			attribute_names = md.captures.last.split('_and_')
			method_missing_without_nice_time(method_id, *args, &block) unless attribute_names.all? { |name| self.class.column_methods_hash.include?(name.to_sym) }
			attribute = attribute_names.first
			argument = args.flatten.first || "%m-%d-%Y"
			argument = "%d-%m-%Y" if argument == :euro
			argument = "%d/%m/%Y" if argument == :euro_slash
			argument = "%m/%d/%Y" if argument == :slash
			#raise args.inspect
			if self.send(attribute.to_sym).class.to_s =~ /Time/
				unless argument == :rss
					self.send(attribute.to_sym).strftime(argument)
				else
					self.send(attribute.to_sym).to_s(:rfc822)
				end
			end
		else
			method_missing_without_nice_time(method_id, *args, &block)
		end
	end

	alias_method_chain :method_missing, :nice_time

	def method_missing_with_seo(method_id, *args, &block)
		method_name = method_id.to_s
		if md = /seo_([_a-zA-Z]\w*)/.match(method_name)
			attribute_names = md.captures.last.split('_and_')
			method_missing_without_seo(method_id, *args, &block) unless attribute_names.all? { |name| self.class.column_methods_hash.include?(name.to_sym) }
			attribute = attribute_names.first
			#raise args.inspect
			if self.send(attribute.to_sym).class == String
				self.id.to_s + "-" + self.send(attribute.to_sym).seo_friendly
			else
				method_missing_without_seo(method_id, *args, &block)
			end
		else
			method_missing_without_seo(method_id, *args, &block)
		end
	end

	alias_method_chain :method_missing, :seo


	def self.new_from_xml(xml_str)
		self.create_obj_from_xml(xml_str, :new)

	end

	def self.create_from_xml(xml_str)
		self.create_obj_from_xml(xml_str, :create)
	end

	private
	def self.create_obj_from_xml(xml_str, creation_method)
		obj_hash = Hash.from_xml(xml_str)

		# if we have multiple records in the XML string, we will have to parse out each record
		if obj_hash.keys.include?(self.class_name.pluralize.downcase)
			output = []
			objects = obj_hash.send(self.class_name.pluralize.downcase).send(self.class_name.downcase)
			objects.each do |object|
				output << self.send(creation_method, object)
			end
			return output
		else
			attribs = obj_hash.send(self.class_name.downcase)

			return self.send(creation_method, attribs)
		end
	end



end